/**
 * Copyright &copy; 2012-2014 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package cn.conac.rc.framework.utils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import org.apache.commons.lang.time.DateFormatUtils;
import org.joda.time.DateTime;
import org.joda.time.Days;

/**
 * 日期工具类, 继承org.apache.commons.lang.time.DateUtils类
 *
 * @author ThinkGem
 * @version 2014-4-15
 */
public class DateUtils extends org.apache.commons.lang.time.DateUtils {
    /**
     * 获取 当前年、半年、季度、月、日、小时 开始结束时间
     */
    private static final SimpleDateFormat shortSdf = new SimpleDateFormat(
            "yyyy-MM-dd");
//    private static final SimpleDateFormat longHourSdf = new SimpleDateFormat(
//            "yyyy-MM-dd HH");
    private static final SimpleDateFormat longSdf = new SimpleDateFormat(
            "yyyy-MM-dd HH:mm:ss");

    public static final String FORMAT_YYYYMMDD = "yyyy-MM-dd";
    public static final String FORMAT_YYYYMM = "yyyy-MM";
    public static final String FORMAT_YYYY = "yyyy";
    /**
     *
     */
    public static final String[] PARSE_PATTERNS = {"yyyy-MM-dd",
            "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", "yyyy/MM/dd",
            "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", "yyyy.MM.dd",
            "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};

    /**
     * 得到当前日期字符串 格式（yyyy-MM-dd）
     *
     * @return String
     */
    public static String getDate() {
        return getDate("yyyy-MM-dd");
    }

    /**
     * 得到当前日期字符串 格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
     *
     * @param pattern String
     * @return String
     */
    public static String getDate(String pattern) {
        return DateFormatUtils.format(new Date(), pattern);
    }

    /**
     * 得到日期字符串 默认格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
     *
     * @param date    Date
     * @param pattern Object
     * @return String
     */
    public static String formatDate(Date date, Object... pattern) {
        String formatDate = null;
        if (pattern != null && pattern.length > 0) {
            formatDate = DateFormatUtils.format(date, pattern[0].toString());
        } else {
            formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
        }
        return formatDate;
    }

    /**
     * 得到日期时间字符串，转换格式（yyyy-MM-dd HH:mm:ss）
     *
     * @param date Date
     * @return String
     */
    public static String formatDateTime(Date date) {
        return formatDate(date, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 得到当前时间字符串 格式（HH:mm:ss）
     *
     * @return String
     */
    public static String getTime() {
        return formatDate(new Date(), "HH:mm:ss");
    }

    /**
     * 得到当前日期和时间字符串 格式（yyyy-MM-dd HH:mm:ss）
     *
     * @return String
     */
    public static String getDateTime() {
        return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 得到当前年份字符串 格式（yyyy）
     *
     * @return String
     */
    public static String getYear() {
        return formatDate(new Date(), "yyyy");
    }

    /**
     * 得到当前月份字符串 格式（MM）
     *
     * @return String
     */
    public static String getMonth() {
        return formatDate(new Date(), "MM");
    }

    /**
     * 得到当天字符串 格式（dd）
     *
     * @return String
     */
    public static String getDay() {
        return formatDate(new Date(), "dd");
    }

    /**
     * 得到当前星期字符串 格式（E）星期几
     *
     * @return String
     */
    public static String getWeek() {
        return formatDate(new Date(), "E");
    }

    /**
     * 日期型字符串转化为日期 格式 { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm",
     * "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy.MM.dd",
     * "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm" }
     *
     * @param str Object
     * @return Date
     */
    public static Date parseDate(Object str) {
        if (str == null) {
            return null;
        }
        try {
            return parseDate(str.toString(), PARSE_PATTERNS);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 获取过去的天数
     *
     * @param date Date
     * @return long
     */
    public static long pastDays(Date date) {
        long t = new Date().getTime() - date.getTime();
        return t / (24 * 60 * 60 * 1000);
    }
    
    
    /**
     * 获取剩余的天数
     *
     * @param date Date
     * @return long
     */
    public static long remDays(Date date) {
        long t = date.getTime() -  new Date().getTime();
        return t / (24 * 60 * 60 * 1000);
    }

    /**
     * 获取过去的小时
     *
     * @param date Date
     * @return long
     */
    public static long pastHour(Date date) {
        long t = new Date().getTime() - date.getTime();
        return t / (60 * 60 * 1000);
    }

    /**
     * 获取过去的分钟
     *
     * @param date Date
     * @return long
     */
    public static long pastMinutes(Date date) {
        long t = new Date().getTime() - date.getTime();
        return t / (60 * 1000);
    }

    /**
     * 转换为时间（天,时:分:秒.毫秒）
     *
     * @param timeMillis long
     * @return String
     */
    public static String formatDateTime(long timeMillis) {
        long day = timeMillis / (24 * 60 * 60 * 1000);
        long hour = (timeMillis / (60 * 60 * 1000) - day * 24);
        long min = ((timeMillis / (60 * 1000)) - day * 24 * 60 - hour * 60);
        long s = (timeMillis / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        long sss = (timeMillis - day * 24 * 60 * 60 * 1000 - hour * 60 * 60
                * 1000 - min * 60 * 1000 - s * 1000);
        return (day > 0 ? day + "," : "") + hour + ":" + min + ":" + s + "."
                + sss;
    }

    /**
     * 获取两个日期之间的天数
     *
     * @param before Date
     * @param after  Date
     * @return double
     */
    public static double getDistanceOfTwoDate(Date before, Date after) {
        long beforeTime = before.getTime();
        long afterTime = after.getTime();
        return (afterTime - beforeTime) / (1000 * 60 * 60 * 24);
    }

    /**
     * 功能: 计算2个日期之间天数
     *
     * @param start 开始时间
     * @param end   结束时间
     * @return 会有负值
     * @author zhangfz
     * @since 2015-2-13
     */
    public static int getDayInterval(Date start, Date end) {
        DateTime dt1 = new DateTime(start);
        DateTime dt2 = new DateTime(end);
        return Days.daysBetween(dt1, dt2).getDays();
    }

    /**
     * 功能:将当天的时分秒变成0
     *
     * @param date Date
     * @return Date
     */
    public static Date getDateStart(Date date) {
        if (date == null) {
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            date = sdf.parse(formatDate(date, "yyyy-MM-dd") + " 00:00:00");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 功能:日期后加23：59：59
     *
     * @param date Date
     * @return Date
     */
    public static Date getDateEnd(Date date) {
        if (date == null) {
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            date = sdf.parse(formatDate(date, "yyyy-MM-dd") + " 23:59:59");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 功能: 取发布距离当前时间取发布距离当前时间<br>
     * 小于60分钟使用分钟,大于60分钟小于1440分钟使用小时数,大于1440小于42300使用天数,大于42300小于518400使用月数,
     * 大于518400使用年数
     *
     * @param millisecode 毫秒数
     * @return xx分钟前 xx小时前 xx天前
     * @author zhangfz
     * @since 2015-2-12
     */
    public static String getRelativeTime(long millisecode) {
        // 当前时间
        long now = System.currentTimeMillis();
        // 距离分钟数
        long longTime = (now - millisecode) / (1000 * 60);
        String relativeTime = "";
        // 小于60分钟使用分钟,大于60分钟小于1440分钟使用小时数,大于1440小于42300使用天数,大于42300小于518400使用月数,大于518400使用年数
        if (longTime < 60) {
            relativeTime = longTime + "分钟前";
        } else if (longTime < 1440) {
            relativeTime = (longTime / 60) + "小时前";
        } else if (longTime < 42300) {
            relativeTime = (longTime / 60 / 24) + "天前";
        } else if (longTime < 518400) {
            relativeTime = (longTime / 60 / 24 / 30) + "月前";
        } else {
            relativeTime = (longTime / 60 / 24 / 30 / 12) + "年前";
        }
        return relativeTime;
    }

    /**
     * 功能:把UTC时间转化成GMT时间
     *
     * @param datestring String
     * @return Date
     * @throws ParseException  Parse异常
     * @throws IndexOutOfBoundsException IndexOutOfBounds异常
     * @author wenqing
     * @since 2014-3-19
     */

    public static Date parseRFC3339Date(String datestring)
            throws ParseException, IndexOutOfBoundsException {

        Date d = new Date();
        // if there is no time zone, we don't need to do any special parsing.
        if (datestring.endsWith("Z")) {
            try {
                SimpleDateFormat s = new SimpleDateFormat(
                        "yyyy-MM-dd'T'HH:mm:ss'Z'");// spec
                // for
                // RFC3339

                // s.setTimeZone(TimeZone.getTimeZone("UTC"));
                d = s.parse(datestring);

                SimpleDateFormat localFormater = new SimpleDateFormat(
                        "yyyy-MM-dd HH:mm:ss");
                localFormater.setTimeZone(TimeZone.getDefault());
                String localTime = localFormater.format(d.getTime());
                System.out.println(localTime);
            } catch (ParseException pe) {// try again with optional //

                pe.getStackTrace();
                // decimals
                SimpleDateFormat s = new SimpleDateFormat(
                        "yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'");// //
                // spec
                // for
                // RFC3339
                // //
                // (with
                // fractional
                // //seconds)
                s.setLenient(true);
                d = s.parse(datestring);

                // SimpleDateFormat localFormater = new
                // SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                // TimeZone zone = TimeZone.getTimeZone("GMT+8:00");
                // long date=d.getTime();
                // utcToTimeZoneDate(date,zone,localFormater);
            }

        }
        return d;
    }

    /**
     * 获得几天后的日期
     *
     * @param date 参照日期
     * @param days 天数
     * @return days天后的日期
     */
    public static String getDateAfter(String date, int days) {
        Calendar now = Calendar.getInstance();
        Date d = parseDate(date, FORMAT_YYYYMMDD);
        now.setTime(d);
        now.set(Calendar.DATE, now.get(Calendar.DATE) + days);
        return getFormatDateTime(now.getTime(), FORMAT_YYYYMMDD);
    }
    
    /**
     * 获得几天后的日期
     *
     * @param date 参照日期
     * @param days 天数
     * @return days天后的日期
     */
    public static Date getDateAfter(Date date, int days) {
        Calendar now = Calendar.getInstance();
        now.setTime(date);
        now.set(Calendar.DATE, now.get(Calendar.DATE) + days);
        return now.getTime();
    }

    public static String getFormatDateTime(Date date, String format) {
        DateFormat df = new SimpleDateFormat(format);
        return df.format(date);
    }

    public static Date parseDate(String source, String format) {
        DateFormat df = new SimpleDateFormat(format);
        try {
            return df.parse(source);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获得本月的开始时间
     *
     * @return yyyy-MM-dd 00:00:00
     * @author haocm
     */
    public static Date getCurrentMonthStartTime(Calendar c) {
        Date now = null;
        try {
            c.set(Calendar.DATE, 1);
            now = shortSdf.parse(shortSdf.format(c.getTime()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 将时间戳格式的时间转换为yy-MM-dd格式
     * @param timeStampFormat 时间戳格式时间
     * @return yyyy-MM-dd 
     * @author lucj
     */
    public static String formatTimeStamp(String timeStampFormat) {
       String formatDataStr = null;
        try {
        	Long timeStampLong=new Long(timeStampFormat); 
        	formatDataStr = shortSdf.format(timeStampLong);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return formatDataStr;
    }

    
    /**
     * 根据季度返回季度开始日期和结束日期
     *
     * @return
     */
    public static Date getStartDateByQuarter(String year, String Quarter) {
        Date startDate = null;
        if ("1".equals(Quarter)) {
            startDate = DateUtils.parseDate(year + "-" + "01", "yyyy-MM");
            //c.set(Calendar.MONTH, 0);
        } else if ("2".equals(Quarter)) {
            startDate = DateUtils.parseDate(year + "-" + "04", "yyyy-MM");
            //c.set(Calendar.MONTH, 3);
        } else if ("3".equals(Quarter)) {
            startDate = DateUtils.parseDate(year + "-" + "07", "yyyy-MM");
            //c.set(Calendar.MONTH, 6);
        } else if ("4".equals(Quarter)) {
            startDate = DateUtils.parseDate(year + "-" + "10", "yyyy-MM");
        }
        Calendar ca = Calendar.getInstance();
        ca.setTime(startDate);
        return DateUtils.getCurrentMonthStartTime(ca);
    }

    /**
     * 根据季度返回季度开始日期和结束日期
     *
     * @return
     */
    public static Date getEndDateByQuarter(String year, String Quarter) {
        Date endDate = null;
        if ("1".equals(Quarter)) {
            endDate = DateUtils.parseDate(year + "-" + "03", "yyyy-MM");
            //c.set(Calendar.MONTH, 0);
        } else if ("2".equals(Quarter)) {
            endDate = DateUtils.parseDate(year + "-" + "06", "yyyy-MM");
            //c.set(Calendar.MONTH, 3);
        } else if ("3".equals(Quarter)) {
            endDate = DateUtils.parseDate(year + "-" + "09", "yyyy-MM");
            //c.set(Calendar.MONTH, 6);
        } else if ("4".equals(Quarter)) {
            endDate = DateUtils.parseDate(year + "-" + "12", "yyyy-MM");
        }
        Calendar ca = Calendar.getInstance();
        ca.setTime(endDate);
        return DateUtils.getCurrentMonthEndTime(ca);
    }

    /**
     * 指定日期的当前月的结束时间
     *
     * @return yyyy-MM-dd 23:59:59
     * @author haocm
     */
    public static Date getCurrentMonthEndTime(Calendar c) {
        Date now = null;
        try {
            c.set(Calendar.DATE, 1);
            c.add(Calendar.MONTH, 1);
            c.add(Calendar.DATE, -1);
            now = longSdf.parse(shortSdf.format(c.getTime()) + " 23:59:59");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 指定日期的当前年的开始时间
     *
     * @return yyyy-MM-dd 00:00:00
     * @author haocm
     */
    public static Date getCurrentYearStartTime(Calendar c) {
        Date now = null;
        try {
            c.set(Calendar.MONTH, 0);
            c.set(Calendar.DATE, 1);
            now = shortSdf.parse(shortSdf.format(c.getTime()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 指定日期的当前年的结束时间
     *
     * @return yyyy-MM-dd 23:59:59
     * @author haocm
     */
    public static Date getCurrentYearEndTime(Calendar c) {
        Date now = null;
        try {
            c.set(Calendar.MONTH, 11);
            c.set(Calendar.DATE, 31);
            now = longSdf.parse(shortSdf.format(c.getTime()) + " 23:59:59");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 指定日期的当前季度的开始时间
     *
     * @return yyyy-MM-dd 00:00:00
     * @author haocm
     */
    public static Date getCurrentQuarterStartTime(Calendar c) {
        int currentMonth = c.get(Calendar.MONTH) + 1;
        Date now = null;
        try {
            if (currentMonth >= 1 && currentMonth <= 3)
                c.set(Calendar.MONTH, 0);
            else if (currentMonth >= 4 && currentMonth <= 6)
                c.set(Calendar.MONTH, 3);
            else if (currentMonth >= 7 && currentMonth <= 9)
                c.set(Calendar.MONTH, 6);
            else if (currentMonth >= 10 && currentMonth <= 12)
                c.set(Calendar.MONTH, 9);
            c.set(Calendar.DATE, 1);
            now = longSdf.parse(shortSdf.format(c.getTime()) + " 00:00:00");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 指定日期的当前季度的结束时间
     *
     * @return yyyy-MM-dd 23:59:59
     * @author haocm
     */
    public static Date getCurrentQuarterEndTime(Calendar c) {
        int currentMonth = c.get(Calendar.MONTH) + 1;
        Date now = null;
        try {
            if (currentMonth >= 1 && currentMonth <= 3) {
                c.set(Calendar.MONTH, 2);
                c.set(Calendar.DATE, 31);
            } else if (currentMonth >= 4 && currentMonth <= 6) {
                c.set(Calendar.MONTH, 5);
                c.set(Calendar.DATE, 30);
            } else if (currentMonth >= 7 && currentMonth <= 9) {
                c.set(Calendar.MONTH, 8);
                c.set(Calendar.DATE, 30);
            } else if (currentMonth >= 10 && currentMonth <= 12) {
                c.set(Calendar.MONTH, 11);
                c.set(Calendar.DATE, 31);
            }
            now = longSdf.parse(shortSdf.format(c.getTime()) + " 23:59:59");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 获取两个时间的差值秒
     *
     * @param d1
     * @param d2
     * @return
     */
    public static Integer getSecondBetweenDate(Date d1, Date d2) {
        Long second = (d2.getTime() - d1.getTime()) / 1000;
        return second.intValue();
    }

    /**
     * main
     *
     * @param args String[]
     * @throws ParseException Parse异常
     */
    public static void main(String[] args) throws ParseException {
        String echarStartDate;
        String echarEndDate;
        String startDate;
        String endDate;
        String dateFlag = "2";
        // cc.add(Calendar.MONTH, -6);// 把日期往后增加一天.正数往后推,负数往前推
        if ("1".equals(dateFlag)) {
            // 本月
            Calendar current = Calendar.getInstance();
            startDate = DateUtils.formatDate(
                    DateUtils.getCurrentMonthStartTime(current),
                    DateUtils.FORMAT_YYYYMMDD);
            current = Calendar.getInstance();
            endDate = DateUtils.formatDate(
                    DateUtils.getCurrentMonthEndTime(current),
                    DateUtils.FORMAT_YYYYMMDD);
            // echar 不包含本月，开始日期是当前日期月份-7 结束如期是当前月份-1
            Calendar c = Calendar.getInstance();
            c.add(Calendar.MONTH, -6);
            echarStartDate = DateUtils.formatDate(
                    DateUtils.getCurrentMonthStartTime(c),
                    DateUtils.FORMAT_YYYYMMDD);
            c = Calendar.getInstance();
            c.add(Calendar.MONTH, -1);
            echarEndDate = DateUtils.formatDate(
                    DateUtils.getCurrentMonthEndTime(c),
                    DateUtils.FORMAT_YYYYMMDD);
        } else if ("2".equals(dateFlag)) {
            // 本季
            Calendar current = Calendar.getInstance();
            Date currentQuarterStartTime = DateUtils
                    .getCurrentQuarterStartTime(current);
            startDate = DateUtils.formatDate(currentQuarterStartTime,
                    DateUtils.FORMAT_YYYYMMDD);
            endDate = DateUtils.formatDate(
                    DateUtils.getCurrentQuarterEndTime(current),
                    DateUtils.FORMAT_YYYYMMDD);
            // echar 不包含本季度，往前6个季，每季度3个月，共18个月
            Calendar c = Calendar.getInstance();
            c.setTime(currentQuarterStartTime);
            c.add(Calendar.MONTH, -18);
            echarStartDate = DateUtils.formatDate(
                    DateUtils.getCurrentMonthStartTime(c),
                    DateUtils.FORMAT_YYYYMMDD);
            c = Calendar.getInstance();
            c.setTime(currentQuarterStartTime);
            c.add(Calendar.MONTH, -1);
            echarEndDate = DateUtils.formatDate(
                    DateUtils.getCurrentMonthEndTime(c),
                    DateUtils.FORMAT_YYYYMMDD);
        } else {
            // 本年
            Calendar current = Calendar.getInstance();
            startDate = DateUtils.formatDate(
                    DateUtils.getCurrentYearStartTime(current),
                    DateUtils.FORMAT_YYYYMMDD);
            endDate = DateUtils.formatDate(
                    DateUtils.getCurrentYearEndTime(current),
                    DateUtils.FORMAT_YYYYMMDD);
            Calendar c = Calendar.getInstance();
            c.add(Calendar.YEAR, -6);
            echarStartDate = DateUtils.formatDate(
                    DateUtils.getCurrentYearStartTime(c),
                    DateUtils.FORMAT_YYYYMMDD);
            c = Calendar.getInstance();
            c.add(Calendar.YEAR, -1);
            echarEndDate = DateUtils.formatDate(
                    DateUtils.getCurrentYearEndTime(c),
                    DateUtils.FORMAT_YYYYMMDD);
            // echar 不包含本年，往前6年
        }
        System.out.println("开始日期：" + startDate);
        System.out.println("截止日期：" + endDate);
        System.out.println("echar开始日期：" + echarStartDate);
        System.out.println("echar截止日期：" + echarEndDate);

        Calendar current = Calendar.getInstance();
        startDate = DateUtils.formatDate(
                DateUtils.getCurrentYearStartTime(current),
                DateUtils.FORMAT_YYYYMMDD);
        System.out.println(startDate);
    }
}
